﻿using Microsoft.Extensions.DependencyInjection;
using Modules.Person.Repositories;
using Modules.Project;
using Modules.Project.Entitys;
using PmSoft;
using PmSoft.ApplicationContext;
using PmSoft.Exceptions;
using static Modules.Person.PersonConstants;

namespace Modules.Person
{
    [UseDI(ServiceLifetime.Scoped)]
    public class PersonBankService
    {
        private readonly PersonBankRepository personBankRepository;
        private readonly IApplicationContext applicationContext;

        public PersonBankService(PersonBankRepository personBankRepository, IApplicationContext applicationContext)
        {
            this.personBankRepository = personBankRepository;
            this.applicationContext = applicationContext;
        }

        /// <summary>
        /// 根据银行卡号获取数据
        /// </summary>
        /// <param name="cardNo"></param>
        /// <returns></returns>
        public PersonBank? GetPersonBankByCardNo(string cardNo)
        {
            return personBankRepository.GetPersonBankByCardNo(cardNo);
        }
        /// <summary>
        /// 根据身份证号获取银行卡信息
        /// </summary>
        /// <param name="cardNo"></param>
        /// <returns></returns>
        //public PersonBank? GetPersonBankByPersonIdCard(string cardNo)
        //{
        //    return personBankRepository.GetPersonBankByPersonCardNo(cardNo);
        //}

        /// <summary>
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public IEnumerable<PersonBank> GetPersonBanksByIdsProjectId(IEnumerable<int> ids, int projectId)
        {
            return personBankRepository.GetPersonBanksByIdsProjectId(ids, projectId);
        }

        public PersonBank? GetPersonBank(int id)
        {
            return personBankRepository.Get(id);
        }

        /// <summary>
        /// 根据身份证号查询工资卡(只有银行卡)
        /// </summary>
        /// <param name="IdCard"></param>
        /// <returns></returns>
        //public PersonBank? GetPersonBankByPersonCardNo(string IdCard)
        //{
        //    return personBankRepository.GetPersonBankByBankNo(IdCard);
        //}

        /// <summary>
        /// 根据身份证号获取默认工资卡
        /// </summary>
        /// <param name="IdCard"></param>
        /// <returns></returns>
        public PersonBank? GetDefaultPersonBankByIdCard(string IdCard)
        {
            if (string.IsNullOrEmpty(IdCard))
                return null;
            var personBanks = GetPersonBanks(IdCard);
            return personBanks.FirstOrDefault();
        }

        public void DeletPersonBanks(IEnumerable<int> ids)
        {
            foreach (int id in ids)
                DeletPersonBank(id);
        }

        public void DeletPersonBank(int id)
        {
            personBankRepository.DeleteByEntityId(id);
        }

        // <summary>
        /// 创建或更新
        /// </summary>
        /// <param name="bank"></param>
        /// <exception cref="ArgumentNullException"></exception>
        public void CreateOrUpdate(PersonBank entity)
        {
            if (!Enum.IsDefined(typeof(工资卡类型), entity.Type))
                throw new BusinessException("工资卡类型只能是银行卡或社会保障卡");

            personBankRepository.CreateOrUpdate(entity);
        }

        /// <summary>
        /// 修改银行卡（无事务）
        /// </summary>
        /// <param name="entity"></param>
        public void UpdatePersonBankNoTransaction(PersonBank entity)
        {
            personBankRepository.Update(entity);
        }

        public IPagedList<PersonBank> GetPersonBanks(PersonBankQuery query, int pageIndex, int pageSize)
        {
            return personBankRepository.GetPersonBanks(query, pageIndex, pageSize);
        }

        /// <summary>
        /// 获取身份证下所有银行卡信息
        /// </summary>
        /// <param name="idCard"></param>
        /// <returns></returns>
        public IEnumerable<PersonBank> GetPersonBanks(string idCard)
        {
            return personBankRepository.GetPersonBanks(idCard);
        }

        /// <summary>
        /// 通过身份证号集合获取关联银行卡
        /// </summary>
        /// <param name="idCards"></param>
        /// <returns></returns>
        public IEnumerable<PersonBank> GetPersonBanksByIdCards(IEnumerable<string> idCards)
        {
            return personBankRepository.GetPersonBanksByIdCards(idCards);
        }

        public void ImportSubmit(List<PersonBank> personBanks, int projectId)
        {
            var projectGroupMemberService = applicationContext.GetService<ProjectGroupMemberService>();
            var personService = applicationContext.GetService<PersonService>();

            IEnumerable<ProjectGroupMember> projectGroupMembers = projectGroupMemberService.GetProjectGroupMembersByProjectId(projectId);
            IEnumerable<PersonInfo> personInfos = personService.GetPersonsByPersonIds(projectGroupMembers.Select(a => a.PersonId));
            IEnumerable<PersonBank> banks = GetPersonBanksByIdCards(personBanks.Select(a => a.IdCard));
            applicationContext.Transaction.Begin();
            foreach (var personBank in personBanks)
            {
                if (personInfos.Where(a => a.CardNumber == personBank.IdCard).Count() == 0)
                {
                    applicationContext.Transaction.Abort();
                    throw new BusinessException($"当前人员{personBank.IdCard}：不是当前项目下的人，不能导入银行卡信息");
                }
                var bank = banks.Where(a => a.IdCard == personBank.IdCard && a.Type == personBank.Type).FirstOrDefault();
                if (bank != null)
                {
                    DeletPersonBank(bank.Id);
                }
                personBank.CreateTime = DateTime.Now;
                CreateOrUpdate(personBank);
            }
            applicationContext.Transaction.Complete();
        }
    }
}